﻿package core.containers
{
	import com.greensock.TweenLite;
	
	import core.CardItemObject;
	import core.Config;
	import core.Model;
	import core.Util;
	import core.controller.AddChipToPlayerController;
	import core.controller.RemoveCardController;
	import core.events.GameEvent;
	import core.manager.RuleManager;
	import core.manager.SoundManager;
	
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.utils.setTimeout;
	
	public class CardContainer extends Sprite
	{
		public var cardTextField:CardPointTextField;
		
		private var container:Sprite;// 专门 处理牌的
		
		private var chipEffectContainer:ChipEffectContainer;
		
		public var owner:int;
		
		private var insureEffectContainer:ChipEffectContainer;
		
		public function CardContainer()
		{
			super();
			this.mouseChildren = false;
			this.mouseEnabled = false;
			this.createChildren();
		}
		
		protected function createChildren():void {
			this.cardTextField = new CardPointTextField();
			this.addChild(this.cardTextField);
			this.container = new Sprite();
			this.addChild(this.container);
			this.chipEffectContainer = new ChipEffectContainer(true);
			this.chipEffectContainer.addEventListener(GameEvent.UPDATE_PLAYER_TABLE,updatePlayerTable);
			this.addChild(this.chipEffectContainer);
			
			this.insureEffectContainer = new ChipEffectContainer(true);
			this.addChild(this.insureEffectContainer);
		}
		
		private function updatePlayerTable(event:GameEvent):void {
			this.dispatchEvent(new GameEvent(GameEvent.UPDATE_PLAYER_TABLE_STATE));
		}
		/**
		 * 添加牌,直接在这里实现效果 ,当完成时,发送一个事件
		 * @param value
		 * 
		 */		
		public function addCard():void {
			var cardEffect:CardEffect = new CardEffect();
			cardEffect.owner = owner;
			var positoin:Point = this.globalToLocal(new Point(Config.SEND_CARD_POSITION.x,Config.SEND_CARD_POSITION.y));
			cardEffect.x = positoin.x;
			cardEffect.y = positoin.y;
			this.container.addChild(cardEffect);
			cardEffect.data = Model.instance.random();
			cardEffect.showCardEffect();
			var items:Array = [];
			for(var i:int = 0; i < this.container.numChildren; i++){
				var child:CardEffect = this.container.getChildAt(i) as CardEffect;
				if(child.owner == owner){
					items.push(child);
				}
			}
			var hGap:Number = Config.SEND_CARD_H_GAP;
			var startPoint:Point = this.globalToLocal(Config.PLAYER_TABLE_POSITION[owner]);
			var count:int = items.length - 1;
			var newPosition:Point = new Point(0,0);
			newPosition.x = startPoint.x + count * hGap;
			newPosition.y = startPoint.y;
			
			//显示牌的点数
			
			SoundManager.instance.play("card_moves");
			TweenLite.to(cardEffect,0.15,{x:newPosition.x,y:newPosition.y,onComplete:addCardCompleted});//计算牌的点数，每发一张
		}
		
		private function addCardCompleted():void {
			if(this.container.numChildren > 2){
				this.playSound();
			}
			var c1:CardEffect = this.container.getChildAt(0) as CardEffect;
			this.cardTextField.text = this.points;
			this.cardTextField.x = -this.cardTextField.width - c1.x - 25;
			this.cardTextField.y = -(c1.height - this.cardTextField.height) / 2;
			this.dispatchEvent(new GameEvent(GameEvent.SEND_CARD_COMPLETE));
		}
		
		public function playSound():void {
			var count:int = this.container.numChildren;
			var p:int = this.points;
			if(p == Config.MAX_POINTS){
				if(count == 2){
					if(this.owner == 5){
						SoundManager.instance.play("dealer_has_blackjack");
					}else {
						SoundManager.instance.play("soundblackjack");
					}
				}else {
					SoundManager.instance.playPoints(p);
				}
			}else {
				SoundManager.instance.playPoints(p);
			}
		}
		
		public function getCardObjectItems():Array {
			var list:Array = [];
			for(var i:int = 0; i < this.container.numChildren; i++){ 
				var cardEffect:CardEffect = this.container.getChildAt(i) as CardEffect;
				if(cardEffect.owner == this.owner){
					list.push(cardEffect.data);
				}
			}
			return list;
		}
		
		private var chips:Array = [];
		
		public function addChip(position:Point,data:Object):void {
			if(this.chips.length == 0){
				SoundManager.instance.play("snd_chipPlace_soft");
			}
			position = this.globalToLocal(position);
			var chipEffect:ChipEffect = new ChipEffect();
			chipEffect.scaleX = chipEffect.scaleY = 0.5;
			chipEffect.data = data;
			chipEffect.x = position.x;
			chipEffect.y = position.y;
			this.addChild(chipEffect);
			var p:Point = this.globalToLocal(Config.PLAYER_TABLE_CHIP_POSITION[owner]);
			var center:Point = Util.getCenter(position,p);
			TweenLite.to(chipEffect, 0.5, {bezierThrough:[{x:center.x, y:center.y},{x:p.x,y:p.y}],onComplete:tweenCompleted,onCompleteParams:[data,chipEffect]});
		}
		
		public function get totalNumber():Number {
			var total:Number = 0;
			for(var i:int = 0; i < this.chips.length; i++){// 算出总数
				var n:Number = this.chips[i];
				total += n;
			}
			return total;
		}
		
		private function tweenCompleted(data:Object,chipEffect:ChipEffect):void {
			this.chipEffectContainer.x = chipEffect.x;
			this.chipEffectContainer.y = chipEffect.y;
			Util.removeChild(chipEffect);
			if(this.chips.length > 0){
				SoundManager.instance.play("snd_ChipStack2");
			}
			var v:Number = data.value;
			this.chips.push(v);
			chipEffectContainer.add(Util.split(this.totalNumber));
		}
		
		public function reduction(position:Point):void {
			var v:Number = this.chips.pop();
			var items:Array = Util.split(v);
			var target:ChipEffectContainer = new ChipEffectContainer();
			var p:Point = this.localToGlobal(new Point(this.chipEffectContainer.x,this.chipEffectContainer.y));
			target.x = p.x;
			target.y = p.y;
			target.add(items);
			this.parent.parent.addChild(target);
			var center:Point = Util.getCenter(position,p);
			TweenLite.to(target, 0.5, {bezierThrough:[{x:center.x, y:center.y},{x:position.x,y:position.y}],alpha:0.3,onComplete:function():void {
				Util.removeChild(target);
			}});
			this.chipEffectContainer.add(Util.split(this.totalNumber));
			if(this.chips.length == 0){// 如果为0就没有了
				Model.instance.splice(owner);
			}
		}
		
		private var _item:Object;
		
		public function get item():Object {
			return this._item;
		}
		
		public function split(callback:Function):void {
			this.callback = callback;
			SoundManager.instance.play("split.wav");
			var c1:CardEffect = this.container.getChildAt(0) as CardEffect;
			var c2:CardEffect = this.container.getChildAt(1) as CardEffect;
			var nextOwner:int = owner + 6;// 分出来的数据
			var p:Point = this.globalToLocal(Config.PLAYER_TABLE_POSITION[nextOwner]);
			this._item = {cardItemObject:c2.data,v:this.chipEffectContainer.total};
			TweenLite.to(c2,0.4,{x:p.x,y:p.y,onComplete:function():void {
				Util.removeChild(c2);
				callback();
			}});
		}
		
		public function double(position:Point):void {
			var t:Number = Util.fixedNumber(this.totalNumber);
			var list:Array = Util.split(t);
			this.chips.push(t);
			var target:ChipEffectContainer = new ChipEffectContainer();
			target.add(list);
			target.x = position.x;
			target.y = position.y;
			this.parent.parent.addChild(target);
			var p:Point = Config.PLAYER_TABLE_CHIP_POSITION[this.owner];
			var center:Point = Util.getCenter(position,p);
			TweenLite.to(target, 0.5, {bezierThrough:[{x:center.x, y:center.y},{x:p.x,y:p.y}],onComplete:function():void {
				chipEffectContainer.add(Util.split(totalNumber));
				Util.removeChild(target);
				if(callback != null){
					callback();
					callback = null;
				}
				if(chips.length > 0){
					SoundManager.instance.play("snd_ChipStack2");
				}
			}});
		}
		
		
		public function sendDouble(position:Point,callback:Function):void {
			SoundManager.instance.play("double");
			this.callback = callback;
			this.double(position);
		}
		
		public function repeat(position:Point):void {
			var v:Number = this._realChips;
			var list:Array = Util.split(v);
			this.chips.push(v);
			var target:ChipEffectContainer = new ChipEffectContainer();
			target.add(list);
			target.x = position.x;
			target.y = position.y;
			this.parent.parent.addChild(target);
			var p:Point = Config.PLAYER_TABLE_CHIP_POSITION[this.owner];
			var center:Point = Util.getCenter(position,p);
			TweenLite.to(target, 0.5, {bezierThrough:[{x:center.x, y:center.y},{x:p.x,y:p.y}],onComplete:function():void {
				chipEffectContainer.add(Util.split(totalNumber));
				Util.removeChild(target);
				SoundManager.instance.play("snd_chipPlace_soft");
			}});
		}
		
		public function clear(position:Point):void {
			var target:ChipEffectContainer = new ChipEffectContainer();
			this.parent.parent.addChild(target);
			var p:Point = this.localToGlobal(new Point(this.chipEffectContainer.x,this.chipEffectContainer.y));
			target.x = p.x;
			target.y = p.y;
			var v:Number = this.totalNumber;
			var items:Array = Util.split(v);
			target.add(items);
			var center:Point = Util.getCenter(position,p);
			this.init();
			//this.chipEffectContainer.removeAllChindren();
			TweenLite.to(target, 0.5, {bezierThrough:[{x:center.x, y:center.y},{x:position.x,y:position.y}],onComplete:function():void {
				Util.removeChild(target);
			}});
		}
		
		public function get isA():Boolean {
			var cardEffect:CardEffect = this.container.getChildAt(0) as CardEffect;
			return (cardEffect.data as CardItemObject).isA;
		}
		
		public function get points():int {
			var list:Array = [];
			for(var i:int = 0; i < this.container.numChildren; i++){
				var cardEffect:CardEffect = this.container.getChildAt(i) as CardEffect;
				list.push(cardEffect.data);
			}
			return RuleManager.instance.calculatePoint(list);
		}
		
		public function get cardEffects():Array {
			var list:Array = [];
			for(var i:int = 0; i < this.container.numChildren; i++){
				var cardEffect:CardEffect = this.container.getChildAt(i) as CardEffect;
				list.push(cardEffect);
			}
			return list;
		}
		
		private var callback:Function;
		
		public function bomb(callback:Function = null):void {
			setTimeout(bombFunc,500,callback);
		}
		
		private function bombFunc(callback:Function = null):void {
			this.callback = callback;
			SoundManager.instance.play("dealer_wins");
			var removeEffectController:RemoveCardController = new RemoveCardController(cardEffects,moveCards);//合牌
			var target:ChipEffectContainer = new ChipEffectContainer(); // 移动筹码
			this.parent.parent.addChild(target);
			var p:Point = this.localToGlobal(new Point(this.chipEffectContainer.x,this.chipEffectContainer.y));
			target.x = p.x;
			target.y = p.y;
			target.add(Util.split(this.totalNumber));
			TweenLite.to(target,0.5,{x:Config.REMOVE_CHIP_POSITION.x,y:Config.REMOVE_CHIP_POSITION.y,onComplete:function():void {
				Util.removeChild(target);
			}});
			this.chipEffectContainer.removeAllChindren();
			Util.removeChild(cardTextField);// 删除文本
		}
		
		private var _realChips:Number = 0;
		
		public function get realChips():Number {
			return this._realChips;
		}
		
		public function init():void {
			var t:Number = this.totalNumber;
			if(this._splitable){
				this._realChips = this._doubleabled ?  t : t * 0.5;
			}else {
				this._realChips = t;
			}
			
			this.chips = [];
			try {
				var index:int = this.getChildIndex(this.chipEffectContainer);
				var nextIndex:int = this.getChildIndex(this.container);
				if(index < nextIndex){
					this.swapChildrenAt(index,nextIndex);
				}
			}catch(error:Error){
				
			}
			this._splitable = true;
			this._doubleabled = true;
			this._insureable = true;
			this._insureValue = 0;
			this._item = null;
			this.callback = null;
			this.chipEffectContainer.removeAllChindren();
			Util.removeChild(this.cardTextField);
			this.cardTextField = new CardPointTextField();
			this.addChildAt(this.cardTextField,0);
		}
		/**
		 * 平局 
		 * 
		 */		
		public function dogfall(value:ChipEffectContainer,callback:Function = null):void {
			SoundManager.instance.play("push.wav");
			this.callback = callback;
			var removeEffectController:RemoveCardController = new RemoveCardController(cardEffects,moveCards);//合牌
			
			var global:Point = this.localToGlobal(new Point(this.chipEffectContainer.x,this.chipEffectContainer.y));
			var nextEffectContainer:ChipEffectContainer = this.chipEffectContainer.clone();
			nextEffectContainer.x = global.x;
			nextEffectContainer.y = global.y;
			this.parent.parent.parent.addChild(nextEffectContainer);
			var addChipController:AddChipToPlayerController = new AddChipToPlayerController(null,nextEffectContainer,value,null,null);
			addChipController.execute();
			this.chipEffectContainer.removeAllChindren();
			this.cardTextField.text = "";
		}
		
		public function remove(callback:Function = null):void {
			this.callback = callback;
			var removeEffectController:RemoveCardController = new RemoveCardController(cardEffects,moveCards);//合牌
		}
		
		private function moveCards():void {
			Model.instance.shift();
			var p:Point = new Point(this.container.x,this.container.y);
			var global:Point = this.localToGlobal(p);
			this.container.x = global.x;
			this.container.y = global.y;
			this.parent.parent.addChild(this.container);
			TweenLite.to(this.container,0.5,{x:Config.REMOVE_CARD_POSITION.x,y:Config.REMOVE_CARD_POSITION.y,onComplete:function():void {
				Util.removeAllChildren(container);
				addChild(container);
				container.x = p.x
				container.y = p.y;
			}});
			if(this.callback != null){
				this.callback();
			}
			this.chipEffectContainer.removeAllChindren();
			this.cardTextField.text = "";
			
		}
		
		public function win(value:ChipEffectContainer,callback:Function):void {
			this.callback = callback;
			setTimeout(winFunc,500,value);
		}
		
		public function addInsure(value:ChipEffectContainer,total:Number):void {
			var target:ChipEffectContainer = new ChipEffectContainer();
			target.add(Util.split(total));
			target.x = Config.REMOVE_CHIP_POSITION.x;
			target.y = Config.REMOVE_CHIP_POSITION.y;
			this.parent.parent.parent.addChild(target);
			
			var global:Point = this.localToGlobal(new Point(cardTextField.x,cardTextField.y));
			var p:Point = new Point(global.x,global.y + 50);
			
			global = this.localToGlobal(new Point(this.insureEffectContainer.x,this.insureEffectContainer.y));
			var nextEffectContainer:ChipEffectContainer = this.insureEffectContainer.clone();
			nextEffectContainer.x = global.x;
			nextEffectContainer.y = global.y;
			this.parent.parent.parent.addChild(nextEffectContainer);
			var addChipController:AddChipToPlayerController = new AddChipToPlayerController(target,nextEffectContainer,value,p,removeInsureChipEffect);
			addChipController.execute();
		}
		
		private function removeInsureChipEffect():void {
			this.insureEffectContainer.removeAllChindren();
		}
		
		private function winFunc(value:ChipEffectContainer):void {
			SoundManager.instance.play("player_wins.wav");
			var target:ChipEffectContainer = new ChipEffectContainer();
			var n:Number = this.totalNumber;
			var total:Number = this.isBlackJack ? n * 1.5 : n;
			target.add(Util.split(total));
			target.x = Config.REMOVE_CHIP_POSITION.x;
			target.y = Config.REMOVE_CHIP_POSITION.y;
			this.parent.parent.parent.addChild(target);
			
			var global:Point = this.localToGlobal(new Point(cardTextField.x,cardTextField.y));
			var p:Point = new Point(global.x,global.y + 50);
			
			global = this.localToGlobal(new Point(this.chipEffectContainer.x,this.chipEffectContainer.y));
			var nextEffectContainer:ChipEffectContainer = this.chipEffectContainer.clone();
			nextEffectContainer.x = global.x;
			nextEffectContainer.y = global.y;
			this.parent.parent.parent.addChild(nextEffectContainer);
			var addChipController:AddChipToPlayerController = new AddChipToPlayerController(target,nextEffectContainer,value,p,this.removeChipEffect);
			addChipController.execute();
			var removeEffectController:RemoveCardController = new RemoveCardController(cardEffects,moveCards);//合牌
		}
		
		private function removeChipEffect():void {
			this.chipEffectContainer.removeAllChindren();
		}
		
		public function get isBlackJack():Boolean {
			var result:Boolean;
			var count:int = this.container.numChildren;
			if(count == 2 && this.points == 21){
				result = true;
			}
			return result;
		}
		
		/**
		 * 从另一个数据里copy出来,主要用于分牌 
		 * @param cardItemObject
		 * @param v
		 * 
		 */		
		public function copy(cardItemObject:CardItemObject,v:Number):void {
			var cardEffect:CardEffect = new CardEffect();
			cardEffect.owner = owner;
			this.container.addChild(cardEffect);
			cardEffect.data = cardItemObject;
			var hGap:Number = Config.SEND_CARD_H_GAP;
			var startPoint:Point = this.globalToLocal(Config.PLAYER_TABLE_POSITION[owner]);
			cardEffect.x = startPoint.x;
			cardEffect.y = startPoint.y;
			
			cardEffect.stopCardEffect();
			this.cardTextField.text = this.points;
			this.cardTextField.x = -this.cardTextField.width - 40;
			this.cardTextField.y = -(this.width - this.cardTextField.height) / 2;
			
			var p:Point = this.globalToLocal(Config.PLAYER_TABLE_CHIP_POSITION[owner]);
			
			this.chipEffectContainer.x = p.x;
			this.chipEffectContainer.y = p.y;
			this.chips.push(v);
			chipEffectContainer.add(Util.split(this.totalNumber));
		}
		
		private var _splitable:Boolean = true;
		
		public function set splitable(value:Boolean):void {
			this._splitable = value;
		}
		
		public function get canSplit():Boolean {
			if(!this._splitable){
				return false;
			}
			var list:Array = this.getCardObjectItems();
			return RuleManager.instance.canSplit(list);
		}
		
		private var _insureable:Boolean = true;// 用做提示
		
		public function set insureable(value:Boolean):void {
			this._insureable = value;
		}
		
		public function get insureable():Boolean {
			return this._insureable;
		}
		
		private var _insureValue:Number = 0;
		
		public function caclulateInsureValue(position:Point):void {
			this._insureValue = this.totalNumber * 0.5;
			
			// 增加一个动画效果
			
			position = this.globalToLocal(position);
			var target:ChipEffectContainer = new ChipEffectContainer();
			target.add(Util.split(this._insureValue));
			target.x = position.x;
			target.y = position.y;
			this.addChild(target);
			var p:Point = this.globalToLocal(Config.PLAYER_TABLE_CHIP_POSITION[owner]).add(new Point(0,-100));
			var center:Point = Util.getCenter(position,p);
			TweenLite.to(target, 0.5, {bezierThrough:[{x:center.x, y:center.y},{x:p.x,y:p.y}],onComplete:insureComplete,onCompleteParams:[target]});
		}
		
		private function insureComplete(value:ChipEffectContainer):void {
			this.insureEffectContainer.x = value.x;
			this.insureEffectContainer.y = value.y;
			this.insureEffectContainer.add(Util.split(value.total));
			Util.removeChild(value);
			SoundManager.instance.play("snd_chipPlace_soft");
		}
		
		public function get insureValue():Number {
			return this._insureValue;
		}
		
		/**
		 * 删除掉保险筹码 
		 * 
		 */		
		public function insureFunc():void {
			var target:ChipEffectContainer = new ChipEffectContainer(); // 移动筹码
			this.parent.parent.addChild(target);
			var p:Point = this.localToGlobal(new Point(this.insureEffectContainer.x,this.insureEffectContainer.y));
			target.x = p.x;
			target.y = p.y;
			target.add(Util.split(insureEffectContainer.total));
			TweenLite.to(target,0.5,{x:Config.REMOVE_CHIP_POSITION.x,y:Config.REMOVE_CHIP_POSITION.y,onComplete:function():void {
				Util.removeChild(target);
			}});
			this.insureEffectContainer.removeAllChindren();
		}
		
		/**
		 * 对比2个哪个大 
		 * 先比较是不是黑jack,如果是黑jack的话,判断cpu
		 * @param value
		 * @return 
		 * 
		 */		
		public function checkBigSmall(value:CardContainer):int {
			if(this.isBlackJack && value.isBlackJack){
				return 0;// 平局
			}
			if(value.isBlackJack && !this.isBlackJack){
				return 1;
			}
			if(!value.isBlackJack && this.isBlackJack){
				return -1;
			}
			
			if(value.points > 21){
				return -1;// 玩家赢	
			}
			
			if(this.points == value.points){
				return 0;// 平局
			}
			
			if(value.points > this.points){
				return 1;
			}
			return -1;
		}
		
		private var _doubleabled:Boolean = true;
		
		public function set doubleabled(value:Boolean):void {
			this._doubleabled = value;
		}
		
		public function get doubleabled():Boolean {
			if(this.owner == Config.CPU_OWNER){
				return false;
			}
			if(this.container.numChildren == 2){
				if(this._doubleabled){
					return true;
				}
			}
			return false;
		}
		
		public function get sendabled():Boolean {
			if((!this._doubleabled) && this.container.numChildren == 3){
				return false;
			}
			return true;
		}
		
		public function get isTwoA():Boolean {
			if(this.container.numChildren == 2){
				var cardItems:Array = this.getCardObjectItems();
				var c1:CardItemObject = cardItems[0];
				var c2:CardItemObject = cardItems[1];
				if(c1.isA && c2.isA){
					return true;
				}
			}
			return false;
		}
	}
}